package org.jaronsource.framework.plugins.search;

import java.lang.reflect.Field;
import java.util.Collection;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.jaronsource.framework.util.BeanUtils;
import org.jaronsource.framework.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class IndexDocumentUtils {

	private final static Logger log = LoggerFactory.getLogger( IndexDocumentUtils.class );

	public static org.apache.lucene.document.Field createClassField( Class<?> clazz ) {
		org.apache.lucene.document.Field luceneField = new org.apache.lucene.document.Field( "className", clazz.getName(), Store.YES, Index.NOT_ANALYZED );
		return luceneField;
	}

	/**
	 * 取得属性的名称
	 * 
	 * @param searchableField
	 * @param field
	 * @return
	 */
	public static String getFieldName(	SearchableField searchableField,
										Field field ) {
		return StringUtils.isBlank( searchableField.value() ) ? field.getName() : searchableField.value();
	}

	/**
	 * 创建索引
	 * 
	 * @param bean
	 * @return
	 */
	public static <T> Document createDocument( T bean ) {

		Class<?> clzss = bean.getClass();
		SearchableBean searchableBean = clzss.getAnnotation( SearchableBean.class );
		if ( searchableBean == null ) { return null; }
		Document doc = new Document();
		// Field[] fields = clzss.getDeclaredFields();
		Collection<Field> fields = BeanUtils.getAllFieldMap( clzss ).values();

		int fieldSize = 0;
		for ( Field field : fields ) {
			String name = field.getName();
			if ( name.equals( "serialVersionUID" ) ) continue;

			SearchableField searchalbeField = field.getAnnotation( SearchableField.class );
			if ( searchalbeField != null ) {
				fieldSize++;
				String value = getFieldValue( bean, field );

				// 对应的属性列名
				String fieldName = getFieldName( searchalbeField, field );
				org.apache.lucene.document.Field indexField = null;
				if ( searchalbeField.pk() ) {
					// 主键使用默认值
					indexField = new org.apache.lucene.document.Field( fieldName, value, org.apache.lucene.document.Field.Store.YES, org.apache.lucene.document.Field.Index.NOT_ANALYZED );
				}
				else {
					Store store = searchalbeField.store();
					Index index = searchalbeField.index();

					indexField = new org.apache.lucene.document.Field( fieldName, value, store, index );
				}

				// 设置权重值
				float boost = searchalbeField.boost();
				indexField.setBoost( boost );
				doc.add( indexField );
			}

		}

		if ( fieldSize > 0 ) return doc;
		return null;

	}

	/**
	 * @param bean
	 * @param field
	 * @return 通过反射获取字段值
	 */
	public static <T> String getFieldValue( T bean, Field field ) {
		try {
			field.setAccessible( true );
			String property = field.get( bean ) == null ? StringUtils.EMPTY : field.get( bean ).toString();
			String value = property == null ? StringUtils.EMPTY : property;
			return value;
		}
		catch ( Exception e ) {
			log.error( "", e );
			return StringUtils.EMPTY;
		}
	}

}